package com.filldream.fastboot.core.aop;

import cn.hutool.crypto.digest.MD5;
import com.filldream.fastboot.common.annotation.RepeatRequestAnnotation;
import com.filldream.fastboot.common.exception.GlobalException;
import com.filldream.fastboot.common.entity.ErrorCode;
import com.filldream.fastboot.common.util.JsonUtil;
import com.filldream.fastboot.common.util.RequestContext;
import com.filldream.fastboot.core.cache.CacheMap;
import com.filldream.fastboot.core.cache.CacheUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;

/**
 * 重复请求注解AOP
 * @author RickSun
 * @see 3.0
 * 2019-05-28 09:28
 */
@Slf4j
@Aspect
@Component
public class RepeatRequestAop {


    /**定义一个切入点*/
    @Pointcut("@annotation(com.filldream.fastboot.common.annotation.RepeatRequestAnnotation)")
    public void repeatRequestAop() {
    }

    /**
     * 前置通知
     * @param pjp
     */
    @Before(value = "repeatRequestAop()")
    public void doCheckEnable(JoinPoint pjp)  {
        //获取注解
        Signature signature = pjp.getSignature();
        MethodSignature methodSignature = (MethodSignature) signature;
        Method targetMethod = methodSignature.getMethod();
        RepeatRequestAnnotation systemLog = targetMethod.getAnnotation(RepeatRequestAnnotation.class);
        int overTime = systemLog.overTime();
        boolean isCheckData = systemLog.checkData();
        boolean isCheckToken = systemLog.addToken();
        boolean isGlobal = systemLog.globalFlag();

        HttpServletRequest request = RequestContext.getRequest();
        String sessionId = new MD5().digestHex(request.getSession().getId());
        String url = request.getRequestURI();
        String key = CacheMap.getKey(CacheMap.REPEAT_REQUEST_DETAIL, url, isGlobal ? "" : sessionId);
        if( isCheckToken && StringUtils.isNotBlank(request.getHeader("token")) ){
            key = CacheMap.getKey(CacheMap.REPEAT_REQUEST_DETAIL, url, sessionId,request.getHeader("token"));
        }
        String cacheValue = CacheUtil.getStr(key);
        String argsJsonMd5 = new MD5().digestHex( JsonUtil.toJson(pjp.getArgs()) );
        if(StringUtils.isNotBlank(cacheValue)){
            if( isCheckData ){
                if( argsJsonMd5.equals(cacheValue) ){
                    CacheUtil.setStr(key,argsJsonMd5,overTime);
                    throw new GlobalException(ErrorCode.REPEAT_REQUEST_ERR.reMsg());
                }
            }else{
                CacheUtil.setStr(key,url,overTime);
                throw new GlobalException(ErrorCode.REPEAT_REQUEST_ERR.reMsg());
            }
        }
        CacheUtil.setStr( key,isCheckData ? argsJsonMd5 : url , overTime );
    }
}
